import 'dart:math';

import 'package:flutter/material.dart';

class AudioWaveView extends StatefulWidget {
  final double height;
  final Color color;

  final Duration duration;
  final Curve curve;
  final double margin;
  final double width;

  const AudioWaveView(
      {Key? key,
      this.height = 12,
      this.margin = 3,
      this.width = 1.5,
      this.color = const Color(0xffE1351F),
      this.duration = const Duration(seconds: 5),
      this.curve = Curves.easeInOut})
      : super(key: key);

  @override
  State<AudioWaveView> createState() => _AudioWaveViewState();
}

class _AudioWaveViewState extends State<AudioWaveView> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  late Animation _animation, _animation1, _animation2;

  @override
  void initState() {
    _controller = AnimationController(vsync: this, duration: widget.duration)..repeat();

    int count = 15;
    final source = List.generate(count, (index) => Random().nextDouble());
    source.add(source.first);
    _animation = TweenSequence([
      ...List.generate(count, (index) {
        return TweenSequenceItem(tween: Tween(begin: source[index], end: source[index + 1]), weight: 100.0 / count + 1);
      }).toList()
    ]).animate(CurvedAnimation(parent: _controller!, curve: widget.curve));

    final source1 = List.generate(count, (index) => Random().nextDouble());
    source1.add(source1.first);
    _animation1 = TweenSequence([
      ...List.generate(count, (index) {
        return TweenSequenceItem(tween: Tween(begin: source1[index], end: source1[index + 1]), weight: 100.0 / count + 1);
      }).toList()
    ]).animate(CurvedAnimation(parent: _controller, curve: widget.curve));
    final source2 = List.generate(count, (index) => Random().nextDouble());
    source2.add(source2.first);
    _animation2 = TweenSequence([
      ...List.generate(count, (index) {
        return TweenSequenceItem(tween: Tween(begin: source2[index], end: source2[index + 1]), weight: 100.0 / count + 1);
      }).toList()
    ]).animate(CurvedAnimation(parent: _controller, curve: widget.curve));

    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
        animation: _controller,
        builder: (context, child) {
          return Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Bar(
                color: widget.color,
                width: widget.width,
                height: _animation.value * widget.height,
              ),
              SizedBox(width: widget.margin),
              Bar(
                color: widget.color,
                width: widget.width,
                height: _animation1.value * widget.height,
              ),
              SizedBox(width: widget.margin),
              Bar(
                color: widget.color,
                width: widget.width,
                height: _animation2.value * widget.height,
              ),
            ],
          );
        });
  }
}

class Bar extends StatelessWidget {
  final double? width;
  final double? height;
  final Color color;

  const Bar({
    Key? key,
    this.width,
    this.height,
    this.color = Colors.white,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
        width: width,
        height: height,
        child: DecoratedBox(
          decoration: BoxDecoration(
            shape: BoxShape.rectangle,
            color: color,
            borderRadius: BorderRadius.vertical(top: Radius.circular(2), bottom: Radius.circular(2)),
          ),
        ));
  }
}
